package com.aces2win.server.entities;

import java.util.ArrayList;
import java.util.Date;

import com.aces2win.server.backtestengine.BrokerFees;
import com.aces2win.shared.beans.WalletBean;

public class Wallet implements BrokerFees{
	
	private double 				balance = 0;
	private int					tradeNumber = 0;
	private	int					winningTrades = 0;
	private	int					losingTrades = 0;
	private	int					longTradeNumber = 0;
	private	int					shortTradeNumber = 0;
	private double				maxDrawDown = 0;
	private double				totalFees = 0;
	private double				longTradeProfits = 0;
	private double				shortTradeProfits = 0;
	private int					consecutiveLoss = 0;
	private int					consecutiveWin = 0;
	private int					currentLossNumber = 0;
	private int					currentWinNumber =0;
	private double				currentDrawDown = 0;
	private ArrayList<Quote>	walletHistory = new ArrayList<Quote>();
	private ArrayList<Trade>	tradeHistory = new ArrayList<Trade>();
	
 	public double calculateFeesAmount(double c) {
		if(c<=1000 && c>0)
			return 2.5;
		if(c>1000&&c<=5000)
			return 5;
		if(c>5000&&c<=7500)
			return 7.5;
		if(c>7500&&c<=10000)
			return 10;
		if(c>10000)
			return c*0.001;
		return 0;
	}

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance,boolean isLong, double maxDrawDown, double fees) {
		// if new balance is lower than previous balance
		// then it's a losing trade else it's a winning trade
		if(this.balance>balance){
			//it's a loss update consecutive Loss Number
			currentWinNumber  = 0;
			currentLossNumber +=1;
			currentDrawDown += (balance-this.balance);
			this.maxDrawDown = currentDrawDown<maxDrawDown?currentDrawDown:maxDrawDown;
			consecutiveLoss = currentLossNumber>consecutiveLoss?currentLossNumber:consecutiveLoss;
			this.setLosingTrades(this.getLosingTrades() + 1);
			if(isLong)
				this.setLongTradeProfits(balance - this.balance);
			else
				this.setShortTradeProfits(balance - this.balance);
		}
		else{
			//it's a win update consecutive win Number
			currentWinNumber  +=1;
			currentLossNumber = 0;
			currentDrawDown = 0;
			consecutiveWin = currentWinNumber>consecutiveWin?currentWinNumber:consecutiveWin;
			
			this.setWinningTrades(this.getWinningTrades() + 1);
		}
		this.setTradeNumber(this.getTradeNumber() + 1);
		
		if(isLong)
			this.setLongTradeNumber(this.getLongTradeNumber() + 1);
		else
			this.setShortTradeNumber(this.getShortTradeNumber() + 1);
		
		this.setTotalFees(this.getTotalFees() + fees);
		this.balance = balance;
	}

	public void setBalance(double balance){
		this.balance=balance;
	}
	public double getMaxDrawDown() {
		return maxDrawDown;
	}

	public int getWinningTrades() {
		return winningTrades;
	}

	private void setWinningTrades(int winningTrades) {
		this.winningTrades = winningTrades;
	}

	public int getLosingTrades() {
		return losingTrades;
	}

	private void setLosingTrades(int losingTrades) {
		this.losingTrades = losingTrades;
	}

	public int getTradeNumber() {
		return tradeNumber;
	}

	private void setTradeNumber(int tradeNumber) {
		this.tradeNumber = tradeNumber;
	}

	public int getLongTradeNumber() {
		return longTradeNumber;
	}

	private void setLongTradeNumber(int longTradeNumber) {
		this.longTradeNumber = longTradeNumber;
	}

	public int getShortTradeNumber() {
		return shortTradeNumber;
	}

	private void setShortTradeNumber(int shortTradeNumber) {
		this.shortTradeNumber = shortTradeNumber;
	}

	public double getTotalFees() {
		return totalFees;
	}

	private void setTotalFees(double totalFees) {
		this.totalFees = totalFees;
	}

	public double getLongTradeProfits() {
		return longTradeProfits;
	}

	private void setLongTradeProfits(double longTradeProfits) {
		this.longTradeProfits = longTradeProfits;
	}

	public double getShortTradeProfits() {
		return shortTradeProfits;
	}

	private void setShortTradeProfits(double shortTradeProfits) {
		this.shortTradeProfits = shortTradeProfits;
	}
	
	public int getConsecutiveLoss() {
		return consecutiveLoss;
	}

	private void setConsecutiveLoss(int consecutiveLoss) {
		this.consecutiveLoss = consecutiveLoss;
	}

	public int getConsecutiveWin() {
		return consecutiveWin;
	}

	private void setConsecutiveWin(int consecutiveWin) {
		this.consecutiveWin = consecutiveWin;
	}

	public void updateWalletHistory(Date d){
		this.walletHistory.add(new Quote(this.getBalance(),d));
	}

	public ArrayList<Quote> getWalletHistory(){
		return this.walletHistory;
	}
	
	public ArrayList<Trade> getTradeHistory(){
		return this.tradeHistory;
	}
	
	public WalletBean toBean(){
		WalletBean w = new WalletBean();
		w.setBalance(this.balance); 
		w.setTradeNumber(this.tradeNumber);
		w.setWinningTrades(this.winningTrades);
		w.setLosingTrades(this.losingTrades);
		w.setLongTradeNumber(this.longTradeNumber);
		w.setShortTradeNumber(this.shortTradeNumber);
		w.setMaxDrawDown(this.maxDrawDown);
		w.setTotalFees(this.totalFees);
		w.setLongTradeProfits(this.longTradeProfits);
		w.setShortTradeProfits(this.shortTradeProfits);
		w.setConsecutiveLoss(this.consecutiveLoss);
		w.setConsecutiveWin(this.consecutiveWin);
		w.setWalletHistory(Quote.convertQuoteList(this.walletHistory));
		return w;
	}
	
	public void addTrade(Trade t){
		double fees = calculateFeesAmount(t.getOpenAmount())+calculateFeesAmount(t.getCloseAmount());
		double profitLoss = t.getCloseAmount()-t.getOpenAmount()-fees;
		setBalance(profitLoss, t.isLong(),t.getMaxDrawDawn(), fees);
		this.tradeHistory.add(t);
	}
}
